package guru.util;

import guru.util.ObjectCall.ObjectCall;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Dictionary;
import java.util.Hashtable;

import org.apache.log4j.Logger;


/**
 * La clase Commando representa una infraestructura para interfaz de comando.
 *
 * 1. Interfaz de comando
 * 2. .Properties
 * 3. Configuracion remota por interfaz de comando.
 */

public class cmndr extends Thread{
    static Logger logger = Logger.getLogger(cmndr.class);
  
    
	static final int CLIENT_PORT=8887;
	static final int LISTENER_PORT=8888;

	int port;
	DatagramSocket socket;
	String tmpstr;
	private boolean stop=false;
	Object server;
	Params params;


	public cmndr(String initFilePath,String mandatoryParams,Object server) throws Exception{
		this.server=server;
		params=new Params(initFilePath,mandatoryParams);

		port=params.intValue("commander.port",LISTENER_PORT);
		socket = new DatagramSocket(port);	
	}

	public String getValue(String key,String def){
		return(params.getValue(key,def));
	}

	public String getValue(String key){
		return(params.getValue(key));
	}

	public int intValue(String key,int def){
		return(params.intValue(key,def));
	}


	public void finalize(){
		stop=true;
	}

	public void run(){
		String tmpstr;


		try{
			//InetAddress group = InetAddress.getByName("230.0.0.1");	
			//socket.joinGroup(group);	

			DatagramPacket packet;
			byte[] buf;
			byte[] buf2;
			InetAddress target;

			executeInitialCommands();



			while(!stop){
				// RECIBIR 
				buf = new byte[256];
				packet = new DatagramPacket(buf, buf.length);

				socket.receive(packet);

				String received = new String(packet.getData());

				// PROCESAR
				tmpstr=process(received.trim());

				// CONTESTAR
				buf2 =tmpstr.getBytes();

				target = packet.getAddress();

				packet = new DatagramPacket(buf2, buf2.length,target,CLIENT_PORT);

				socket.send(packet);

			}


			//socket.leaveGroup(group);
			socket.close();
			logger.info("Commander listener down.");

		}
		catch(Exception e){
			e.printStackTrace();
		}

	}

	private String process(String command){
	    if(command.equalsIgnoreCase("c1")){
		    return("c1 executed");

	    }
	    
	    return("no action taken: received '"+command+"'");
	}

	private String processOld(String command){

		Dictionary map=new Hashtable();
		map.put("server",server);
		ObjectCall call=null;

		try{
			call=new ObjectCall("server."+command,map);
		}
		catch(Exception e){
			logger.error("Error while procesing the directives: "+e,e);
		}

		if(call!=null){
			Object o=call.getReturn();
			if(o!=null){
				return(o.toString());
			}
		}

		return("unknown result");

	}


	void executeInitialCommands(){
		boolean stop=false;
		int line=1;
		String cmd;

		
		while(!stop){
			if((cmd=(String)params.props.get("commander.cmd."+(line++)))==null){
				stop=true;
			}
			else{
				logger.info(process(cmd));
			}
		}

	}


	public static void main(String argv[]) {
		int port=4447;
		byte[] buf;

 		if ((argv.length>2)||(argv.length==0)) {
			System.out.println("java Commander [<port#>] <command>");
			return;
		}

		if (argv.length==2){
			try{
				port=new Integer(argv[0]).intValue();
				buf =argv[1].getBytes();
			}
			catch(Exception e){
				System.out.println("java Commander [<port#>] <command>");
				return;
			}
		}
		else{
			buf =argv[0].getBytes();
		}

		try {
			DatagramSocket socket = new DatagramSocket(CLIENT_PORT);
			//InetAddress group = InetAddress.getByName("230.0.0.1");
			//socket.joinGroup(group);
			InetAddress target = InetAddress.getByName("127.0.0.1");


			DatagramPacket packet;
			packet = new DatagramPacket(buf, buf.length,target,port);

			socket.send(packet);

			buf = new byte[256];
			packet = new DatagramPacket(buf, buf.length);

			socket.receive(packet);

			String received = new String(packet.getData());

			System.out.println(received.trim());


			socket.close();

		} 
		catch (IOException e) {
			e.printStackTrace();
		}
 	}





}
